//
// Created by Administrator on 2025/7/3.
//

#include <DDS/DomainParticipantFactory.h>
#include "sub.h"
#include "IDL_TypeSupport.h"
#include "UserDataTypeListener.h"
#include <DDS/DomainParticipant.h>
sub::sub(const int &id)
{

/* 1. 创建一个participant，可以在此处定制participant的QoS */
/* 建议1：在程序启动后优先创建participant，进行资源初始化*/
/* 建议2：相同的domainId只创建一次participant，重复创建会占用大量资源 */
    participant = DomainParticipantFactory::get_instance()->create_participant(
            id, PARTICIPANT_QOS_DEFAULT/* participant默认QoS */,
            NULL /* listener */, STATUS_MASK_NONE);
    if (participant == NULL) {
        fprintf(stderr, "create_participant error\n");
        subscriber_shutdown(participant);
        return ;
    }
/* 2. 创建一个subscriber，可以在创建subscriber的同时定制其QoS */
/* 建议1：在程序启动后优先创建subscriber*/
/* 建议2：一个participant下创建一个subscriber即可，无需重复创建 */
    subscriber = participant->create_subscriber(
            SUBSCRIBER_QOS_DEFAULT/* 默认QoS */,
            NULL /* listener */, STATUS_MASK_NONE);
    if (subscriber == NULL) {
        fprintf(stderr, "create_subscriber error\n");
        subscriber_shutdown(participant);
        return ;
    }
/* 3. 在创建主题之前注册数据类型 */
/* 建议1：在程序启动后优先进行注册 */
/* 建议2：一个数据类型注册一次即可 */
    type_name = UserDataTypeTypeSupport::get_type_name();
    retcode = UserDataTypeTypeSupport::register_type(
            participant, type_name);
    if (retcode != RETCODE_OK) {
        fprintf(stderr, "register_type error %d\n", retcode);
        subscriber_shutdown(participant);
        return ;
    }
/* 4. 创建主题，并定制主题的QoS */
/* 建议1：在程序启动后优先创建Topic */
/* 建议2：一种主题名创建一次即可，无需重复创建 */
    topic = participant->create_topic(
            "Example UserDataType"/* 主题名，应与发布者主题名一致 */,
            type_name, TOPIC_QOS_DEFAULT/* 默认QoS */,
            NULL /* listener */, STATUS_MASK_NONE);
    if (topic == NULL) {
        fprintf(stderr, "create_topic error\n");
        subscriber_shutdown(participant);
        return ;
    }
/* 5. 创建一个监听器 */
    reader_listener = new UserDataTypeListener();
/* 6. 创建datareader，并定制datareader的QoS */
/* 建议1：在程序启动后优先创建datareader*/
/* 建议2：创建一次即可，无需重复创建 */
/* 建议3：在程序退出时再进行释放 */
/* 建议4：避免打算接收数据时创建datareader，接收数据后删除，该做法消耗资源，
影响性能 */
    reader = subscriber->create_datareader(
            topic, DATAREADER_QOS_DEFAULT/* 默认QoS */,
            reader_listener/* listener */, STATUS_MASK_ALL);
    if (reader == NULL) {
        fprintf(stderr, "create_datareader error\n");
        subscriber_shutdown(participant);
        delete reader_listener;
        return ;
    }

}

sub::~sub()
{
/* 8. 删除所有实体和监听器 */
    subscriber_shutdown(participant);
    delete reader_listener;
}

int sub::subscriber_shutdown(DomainParticipant *participant)
{
    ReturnCode_t retcode;
    int status = 0;
    if (participant != NULL) {
        retcode = participant->delete_contained_entities();
        if (retcode != RETCODE_OK) {
            fprintf(stderr, "delete_contained_entities error %d\n",
                    retcode);
            status = -1;
        }
        retcode =
                DomainParticipantFactory::get_instance()->delete_participant(participant);
        if (retcode != RETCODE_OK) {
            fprintf(stderr, "delete_participant error %d\n",
                    retcode);
            status = -1;
        }
    }
    return status;
}
